package org.bhf.util;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

/**
 * With enhanced (dynamically subclasses) classes, such as those produced by Guice, we lose the annotations
 * on the base class. Thus, we need to search up the class tree for annotations.
 */
public final class AnnotationAccess
{
    public static <T extends Annotation> T getAnnotation( Class<?> objectClass, final Class<T> annotationClass )
    {
        T annotation = null;
        while( annotation == null && !objectClass.getName().startsWith( "java" ) )
        {
            annotation = objectClass.getAnnotation( annotationClass );
            objectClass = objectClass.getSuperclass();
        }
        return annotation;
    }

    public static <T extends Annotation> T getAnnotation( Method method, final Class<T> annotationClass )
    {
        T annotation = null;
        while( annotation == null && method != null )
        {
            annotation = method.getAnnotation( annotationClass );
            method = getSuperMethod( method );
        }
        return annotation;
    }

    private static Method   getSuperMethod( final Method method )
    {
        Class declaringClass = method.getDeclaringClass().getSuperclass();
        while( !declaringClass.getName().startsWith( "java" ) )
        {
            try
            {
                return declaringClass.getMethod( method.getName(), method.getParameterTypes() );
            }
            catch( final NoSuchMethodException nse )
            {
                declaringClass = declaringClass.getSuperclass();
            }
        }
        return null;
    }
}
